--[[

Usage

/click MillButton

]]--

local MillButton = {
	setup = {
		ScrollWheelUp = true;
		ScrollWheelDown = true;
		extraMacroText = "/run b=SkilletStartQueueButton c=UnitCastingInfo(\"player\") ct=GetTime() if not c and b and b:GetText()==\"Process\" and b:IsEnabled() == 1 and (not ot or ct-ot>1.5) then b:Click() ot=ct end";
	};
};

local HERBS = {
	3819,36903,22790,8836,8839,2450,2453,37921,13463,22786,2449,3818,22785,4625,22788,8845,36901,13464,3821,3369,8846,13467,36906,3358,3356,36905,3357,785,22793,13465,22791,22792,2447,13466,8831,765,3820,8838,2452,36907,22789,36904,3355,22787
};

local HERBS2 = {
	765,785,2447,2449,2450,2452,2453,3355,3356,3357,3358,3369,3818,3819,3820,3821,4625,5056,8831,8836,8838,8839,8845,8846,11514,11979,11980,11992,12005,12016,12017,12027,12036,12048,12058,13463,13464,13465,13466,13467,22575,22576,22785,22786,22787,22788,22789,22790,22791,22792,22793,22795,22797,24401,25813,27859,29453,33452,35229,35947,36901,36902,36903,36904,36905,36906,36907,37921,39516,39969,39970
};

local HERBS_MAP = {
};
	

function MillButton_GetInstance()
	return MillButton
end

function MillButton:CreateButton(name)
	local button = CreateFrame("Button", name, nil, "SecureActionButtonTemplate")
	button:SetAttribute("type", "macro");
	button:SetAttribute("macro", false) -- necessary to make it use macrotext	
	button:SetAttribute("macrotext", "")
    button:SetAttribute("unit", nil);
    button:SetAttribute("spell", nil);
    button:SetAttribute("item", nil);
    button:SetAttribute("target-slot", nil);
	button:EnableMouse(true);
	button:EnableKeyboard(true);
	button:RegisterForClicks("LeftButtonUp", "RightButtonUp");
	return button;
end



function MillButton:Init()
	self.setup.button = self:CreateButton("MillButton")
	self.setup.button:SetNormalTexture("Interface\Icons\Ability_Miling")
	--self.setup.button:SetDisabledTexture()
	self.setup.frame = CreateFrame("Frame")
	self.setup.tooltip = CreateFrame("GameTooltip")
	self.setup.frame:SetScript("OnEvent", function() local f = self[event] if type(f) == "function" then f(self) end end)
	self.setup.frame:SetScript("OnUpdate", function() self:OnUpdate() end)
	self.setup.frame:Show();
end

function MillButton:ForceItem(itemId)
	local itemString = "item:"..itemId..":0:0:0:0:0:0:0"
	local tooltip = self.setup.tooltip
	GameTooltip_SetDefaultAnchor(tooltip, UIParent)
	tooltip:SetHyperlink(itemString)
	tooltip:Hide()
end

function MillButton:PerformScan()
	local caughtAll = true
	local k,v, name, link
	for k,v in pairs(HERBS) do
		self:ForceItem(v)
		name, link = GetItemInfo(v)
		if name and link then
			HERBS_MAP[v] = name
			HERBS_MAP[name] = v
		else
			ChatFrame2:AddMessage("nil from "..k..":"..v)
			caughtAll = false
		end
	end
	self.setup.HERBS_MAP = HERBS_MAP
	return caughtAll
end

function MillButton:OnUpdate()
	if not self.setup.caughtAll then
		local curTime = GetTime()
		if not self.setup.lastScan or curTime - self.setup.lastScan > 5 then
			self.setup.lastScan = curTime
			self.setup.caughtAll = self:PerformScan()
		end
	else
		ChatFrame1:AddMessage("MillButton items cached.", 1, 1, 0)
		self.setup.frame:Hide()
		self:RegisterEvent("BAG_UPDATE")
		self:UpdateBags()
	end
end

function MillButton:RegisterEvent(event)
	if type(event) ~= "string" then return end
	if type(self.setup.frame) == "nil" then return end
	if type(self[event]) ~= "function" then self:Warning(event.." does not have a handler") return end
	self.setup.frame:RegisterEvent(event)
end

function MillButton:Warning(msg)
	if type(msg) ~= "string" then return end
	self:Message(msg, 1, 0.1, 0.1)
end

function MillButton:Message(msg, r, g, b)
	if type(msg) ~= "string" then return end
	self:ShowMessage("MillButton: "..msg, r, g, b)
end

function MillButton:ShowMessage(msg, r, g, b)
	if type(msg) ~= "string" then return end
	if type(r) ~= "number" then r = 1 end
	if type(g) ~= "number" then g = 1 end
	if type(b) ~= "number" then b = 0.1 end
	ChatFrame1:AddMessage(msg, r, g, b)
end

function MillButton:BAG_UPDATE()
	self:UpdateBags()
end

function MillButton:UpdateBags()
	self:ScanBags()
	self:UpdateButton()
end

function MillButton:PLAYER_REGEN_ENABLED()
	if self.setup.shouldUpdateAfterCombat then
		self:UpdateButton()
	end
end

function MillButton:DisableButton()
	self.setup.button:Disable()
end

function MillButton:EnableButton()
	self.setup.button:Enable()
end

function MillButton:UpdateButton()
	if InCombatLockdown() then
		self.setup.shouldUpdateAfterCombat = true
		return
	end
	local list = self.setup.herbs
	local entry = nil
	if type(list) == "table" then
		local k, v
		for k, v in pairs(self.setup.herbs) do
			if v.num > 0 and ( entry == nil or self.setup.herbs[entry].num > v.num ) then
				entry = k
			end
		end
	end
	if entry then
		local macroText = "/cast Milling\n/use "..entry
		if type(self.setup.extraMacroText) == "string" and strlen(self.setup.extraMacroText) > 0 then
			if strlen(macroText) > 0 then
				macroText = macroText.."\n"
			end
			macroText = macroText..self.setup.extraMacroText
		end
		if self.setup.debug then
			self:Message(" enabled - macro text set to "..macroText)
		end
		self.setup.button:SetAttribute("macrotext", macroText)
		--self:EnableButton()
	else
		local macroText = ""
		if type(self.setup.extraMacroText) == "string" and strlen(self.setup.extraMacroText) > 0 then
			if strlen(macroText) > 0 then
				macroText = macroText.."\n"
			end
			macroText = macroText..self.setup.extraMacroText
		end
		if self.setup.debug then
			self:Message(" no milling "..macroText)
		end
		self.setup.button:SetAttribute("macrotext", macroText)
		--self:DisableButton()
	end
	self.setup.shouldUpdateAfterCombat = false
end

function MillButton:ScanBags()
	local list = self.setup.herbs
	if type(list) ~= "table" then
		list = {}
		self.setup.herbs = list
	else
		for k,v in pairs(self.setup.herbs) do
			self.setup.herbs[k].total = 0
			self.setup.herbs[k].num = 0
			self.setup.herbs[k].bag = -1
			self.setup.herbs[k].slot = -1
		end
	end
	local bag, slot, itemCount, itemLink, _, itemName
	for bag = 0, 4 do
		for slot = 1, GetContainerNumSlots(bag) do
			itemLink = GetContainerItemLink(bag, slot)
			if type(itemLink) == "string" then
				itemName = GetItemInfo(itemLink)
			else
				itemName = nil
			end
			if type(itemName) == "string" and strlen(itemName) > 0 and self.setup.HERBS_MAP[itemName] then
				_, itemCount = GetContainerItemInfo(bag, slot)
				local entry = self.setup.herbs[itemName]
				if type(entry) ~= "table" then
					entry = {}
					entry.total = 0
					entry.num = 0
					entry.bag = -1
					entry.slot = -1
					self.setup.herbs[itemName] = entry
				end
				if ( ( entry.num == 0 or itemCount < entry.num ) and itemCount >= 5 ) then
					entry.bag = bag
					entry.slot = slot
					entry.num = itemCount
				end
				entry.total = entry.total + itemCount
			end
		end
	end
end

function MillButton:Rebind()
	local MillButton = self.setup.button
  for i = 1, GetNumBindings(), 1 do
    local s = "";
    local command, key1, key2 = GetBinding(i);
    
    if (key1 and key1 == "MOUSEWHEELUP" and command ~= "MillButton") then
      self.OldWheelUp = command;
    elseif (key1 and key1 == "MOUSEWHEELDOWN" and command ~= "MillButton") then
      self.OldWheelDown = command;
    end  
    
    if (command and command == "AUTOFAIRE") then
      if (key1) then
        SetBindingClick(key1, "MillButton");
      end
      if (key2) then
        SetBindingClick(key2, "MillButton");
      end
      break;
    end
  end
  
  if (self.setup.ScrollWheelUp) then
    isKeyUpChanged = true;
    SetOverrideBindingClick(MillButton, false, "MOUSEWHEELUP", "MillButton", "MOUSEWHEELUP");
  else
   SetOverrideBinding(MillButton, false, "MOUSEWHEELUP");
  end
  
  if (self.setup.ScrollWheelDown) then
    SetOverrideBindingClick(MillButton, false, "MOUSEWHEELDOWN", "MillButton", "MOUSEWHEELDOWN");
  else
    SetOverrideBinding(MillButton, false, "MOUSEWHEELDOWN");
  end
end

MillButton:Init()
MillButton:Rebind()



